<?php

    $rootDir = $_SERVER['DOCUMENT_ROOT'];

    require_once($rootDir.'/classes/SessionManager.class.php');

    class SQLiteWMutex {
    
        private static $SQLITE_WRITE_MTX_ID = "sqlite_w.key";
        private static $SQLITE_WRITE_MTX_NID = 0xff4320;
        
        private static $SESSION_KEY = 'SQLiteWMutex';
        
        static private $_semaphore = null;
        
        private function __construct() {
        }
        
        public static function initialize() {
            $sqlite_w_key = ftok($_SERVER['DOCUMENT_ROOT'].'/'.self::$SQLITE_WRITE_MTX_ID, 'b');  
            self::$_semaphore = ($sqlite_w_key != -1) ? sem_get($sqlite_w_key) : sem_get(self::$SQLITE_WRITE_MTX_NID);
            SessionManager::registerVar(self::$SESSION_KEY,self::$_semaphore);
        }        
    
        public function acquireWriteAccess() {
            if (self::$_semaphore == null) {
                if (SessionManager::isVarSet(self::$SESSION_KEY)) {
                    self::$_semaphore = SessionManager::getVar(self::$SESSION_KEY);
                } else self::initialize();
            }
            return (self::$_semaphore != null) ? sem_acquire(self::$_semaphore) : null;
        }
        
        public function releaseWriteAccess() {
            SessionManager::clearVar(self::$SESSION_KEY);
            return (self::$_semaphore != null) ? sem_release(self::$_semaphore) : null;            
        }       
        
        private function __clone() {
        }
    
    }
    
    /* from: http://php.biz.net.id/manual/sv/ref.sem.php#72600
    
    class Mutex
    {
        private $id;
        private $sem_id;
        private $is_acquired = false;
        private $is_windows = false;
        private $filename = '';
        private $filepointer;

        function __construct()
        {
            if(substr(PHP_OS, 0, 3) == 'WIN')
                $this->is_windows = true;
        }

        public function init($id, $filename = '')
        {
            $this->id = $id;

            if($this->is_windows)
            {
                if(empty($filename)){
                    print "no filename specified";
                    return false;
                }
                else
                    $this->filename = $filename;
            }
            else
            {
                if(!($this->sem_id = sem_get($this->id, 1))){
                    print "Error getting semaphore";
                    return false;
                }
            }

            return true;
        }

        public function acquire()
        {
            if($this->is_windows)
            {
                if(($this->filepointer = @fopen($this->filename, "w+")) == false)
                {
                    print "error opening mutex file<br>";
                    return false;
                }
                
                if(flock($this->filepointer, LOCK_EX) == false)
                {
                    print "error locking mutex file<br>";
                    return false;
                }
            }
            else
            {
                if (! sem_acquire($this->sem_id)){
                    print "error acquiring semaphore";
                    return false;
                }
            }

            $this->is_acquired = true;
            return true;
        }

        public function release()
        {
            if(!$this->is_acquired)
                return true;

            if($this->is_windows)
            {
                if(flock($this->filepointer, LOCK_UN) == false)
                {
                    print "error unlocking mutex file<br>";
                    return false;
                }

                fclose($this->filepointer);
            }
            else
            {
                if (! sem_release($this->sem_id)){
                    print "error releasing semaphore";
                    return false;
                }
            }

            $this->is_acquired = false;
            return true;
        }

        public function getId()
        {
            return $this->sem_id;
        }
    }
    
    
    */

?>
